/*******************************************************************************
 * Copyright (c) 2007 University of Oslo.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     University of Oslo - initial API and implementation
 *******************************************************************************/

package com.cea.papyrus.diagram.sequence.sedi.edit;

import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.gef.EditPolicy;
import org.eclipse.uml2.uml.InteractionConstraint;
import org.eclipse.uml2.uml.InteractionOperand;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.ValueSpecification;

import com.cea.papyrus.core.editor.ModelManager;
import com.cea.papyrus.diagram.sequence.sedi.edit.policy.LinkEndpointEditPolicy;
import com.cea.papyrus.diagraminterchange2.di2.GraphEdge;

/**
 * Edit part for Separators between combined fragment operands.
 * 
 * @author Andreas Limyr
 * @author frankd@ifi.uio.no
 */
public class SeparatorEditPart extends AbstractLinkEditPart<InteractionOperand> {

    public SeparatorEditPart(GraphEdge view, ModelManager modelManager) {
        super(view, modelManager);
    }

    protected void createEditPolicies() {
        installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE, new LinkEndpointEditPolicy());
//        installEditPolicy(EditPolicy.CONNECTION_ROLE, new SeparatorEditPolicy());
    }

    protected IFigure createFigure() {
        PolylineConnection figure = new PolylineConnection();
        figure.setLineStyle(Graphics.LINE_DASH);

        return figure;
    }

    // --- Synchronization ---

    @Override
    public void umlModelChanged(Notification evt) {
        switch (evt.getFeatureID(UMLPackage.class)) {
        case UMLPackage.INTERACTION_OPERAND__GUARD:
        case UMLPackage.CONSTRAINT__SPECIFICATION:
            // =case UMLPackage.OPAQUE_EXPRESSION__BODY:
            deactivate(evt.getOldValue());
            activate(evt.getNewValue());
            refreshVisuals();
            break;
        default:
            // ignore
        }
    }

    // --- Activation ---

    @Override
    public void activate() {
        if (!isActive()) {
            super.activate();
            activate(getUmlElement().getGuard());
        }
    }

    @Override
    public void deactivate() {
        if (isActive()) {
            deactivate(getUmlElement().getGuard());
            super.deactivate();
        }
    }

    @SuppressWarnings("unchecked")
    private void activate(Object o) {
        if (o instanceof InteractionConstraint) {
            InteractionConstraint guard = (InteractionConstraint) o;
            guard.eAdapters().add(umlAdapter);
            o = guard.getSpecification();
        }
        if (o instanceof ValueSpecification) {
            ValueSpecification valueSpec = (ValueSpecification) o;
            valueSpec.eAdapters().add(umlAdapter);
        }
    }

    private void deactivate(Object o) {
        if (o instanceof InteractionConstraint) {
            InteractionConstraint guard = (InteractionConstraint) o;
            guard.eAdapters().remove(umlAdapter);
            o = guard.getSpecification();
        }
        if (o instanceof ValueSpecification) {
            ValueSpecification valueSpec = (ValueSpecification) o;
            valueSpec.eAdapters().remove(umlAdapter);
        }
    }

    private final Adapter umlAdapter = new AdapterImpl() {
        public boolean isAdapterForType(Object type) {
            return type instanceof NamedElement;
        }

        public void notifyChanged(Notification msg) {
            if (msg.isTouch())
                return;
            SeparatorEditPart.this.umlModelChanged(msg);
        }
    };
}
